package com.jysz.certificate.service.system;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;

import com.jysz.certificate.Constants;
import com.jysz.certificate.persistence.dao.system.OrganizationDao;
import com.jysz.certificate.persistence.enums.OrganizationEnum;
import com.jysz.certificate.persistence.enums.PostType;
import com.jysz.certificate.persistence.model.system.Organization;
import com.jysz.certificate.persistence.model.system.OrganizationDTO;
import com.jysz.certificate.persistence.model.system.User;
import com.jysz.webcore.ssh.orm.hibernate.ThreadLocalHolder;
import com.jysz.webcore.ssh.orm.hibernate.support.Page;
import com.jysz.webcore.ssh.service.EntityService;

@Service
public class OrganizationService extends EntityService<Organization, Long, OrganizationDao>{
	
	@Resource
	private OrganizationDao organizationDao;

	@Resource
	private UserService userService;
	
	@Override
	public OrganizationDao getEntityDao() {
		return organizationDao;
	}
	
	public Page<Organization> selectShopUser(String shopName,int pageNo, int pageSize){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("type", OrganizationEnum.SHOP));
		if(shopName!=null&&!"".equals(shopName)){
			criteria.add(Restrictions.like("name", shopName,MatchMode.ANYWHERE));
		}
		return this.findPage(criteria, pageNo, pageSize);
		
	}
	
	public Organization getOrg(Long shopId){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("type", OrganizationEnum.SHOP));
		criteria.add(Restrictions.eq("objectId", shopId));
		return (Organization) criteria.uniqueResult();
	}
	/**
	 * 是否允许添加区域经理
	 * @return
	 */
	public boolean getPassManager(Long parentId){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("type", OrganizationEnum.STAFF));
		criteria.add(Restrictions.eq("parent.id", parentId));
		Organization org = (Organization) criteria.uniqueResult();
		return org==null?true:false;
	}
	
	/**
	 * 是否允许修改人员
	 * @return
	 */
	public boolean getUpdateUser(Long userId){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("objectId", userId));
		criteria.add(Restrictions.eq("type", OrganizationEnum.STAFF));
		List list = criteria.list();
		if(list!=null&&list.size()>0){
			return false;
		}
		return true;
	}
	
	
	/**
	 * 是否允许添加人员
	 * @return
	 */
	public boolean getPassUser(Long userId,Long parentId){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("objectId", userId));
		criteria.add(Restrictions.eq("type", OrganizationEnum.STAFF));
		criteria.add(Restrictions.eq("parent.id", parentId));
		Organization org = (Organization) criteria.uniqueResult();
		return org==null?true:false;
	}
	
	public boolean getPassOrg(Long parentId){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("parent.id", parentId));
		List list = criteria.list();
		if(list==null||list.size()==0)
			return true;
		return false;
	}
	
	/**
	 * 是否允许添加店铺
	 * @return
	 */
	public boolean getPassShop(Long shopId){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("objectId", shopId));
		criteria.add(Restrictions.eq("type", OrganizationEnum.SHOP));
		Organization org = (Organization) criteria.uniqueResult();
		return org==null?true:false;
	}

	
	public Page<Organization> findPage(OrganizationDTO search, int pageNo, int pageSize) {
		Criteria criteria = organizationDao.createCriteria();
		criteria.addOrder(Order.asc(Organization.COLUMN_CODE));
		criteria.addOrder(Order.desc(Organization.COLUMN_ORDER));
		if(search!=null){
			if(StringUtils.isNotBlank(search.getName())){
				criteria.add(Restrictions.like(Organization.COLUMN_NAME, search.getName(), MatchMode.ANYWHERE));
			}
			if(null!=search.getBeginDate()){
				criteria.add(Restrictions.ge("createdAt", search.getBeginDate()));
			}
			if(null!=search.getEndDate()){
				criteria.add(Restrictions.le("createdAt", search.getEndDate()));
			}
			
			if(StringUtils.isNotBlank(search.getCode())){
				criteria.add(Restrictions.like("code", search.getCode(), MatchMode.START));
			}
		}
		return this.findPage(criteria, 0, 10000);
	}

	public Integer getMaxOrder(Long parentId) {
		Organization organization = null;
		if(parentId != null ){
			organization = organizationDao.get(parentId);
		}
		return organizationDao.getMaxOrder(organization);
	}
	@SuppressWarnings("unchecked")
	public Organization organizationId(Organization o){
		Criteria criteria = organizationDao.createCriteria();
		Organization organization=null;
		if(null != o){
			criteria.add(Restrictions.eq(Organization.COLUMN_TYPE, OrganizationEnum.SHOP));
			criteria.add(Restrictions.eq(Organization.COLUMN_OBJECT_ID, o.getObjectId()));
			List<Organization> lOrganizations =criteria.list();
			if(lOrganizations.size() > 0)
				organization = lOrganizations.get(0);
		}
		return organization;
	}

	public String genCode(Long parentId) {
		Organization organization = null;
		if(parentId != null ){
			organization = organizationDao.get(parentId);
		}
		Integer order = this.getMaxOrder(parentId) + 1;
		String code = organization != null ? organization.getCode() + "_" + String.format("%1$03d", order) : Constants.CODE_PREFIX_ORG + String.format("%1$03d", order);
		return code;
	}
	
	public String genCode(Organization parent,Integer maxOrder) {
		Organization organization = parent;
		Integer order = maxOrder + 1;
		String code = organization != null ? organization.getCode() + "_" + String.format("%1$03d", order) : Constants.CODE_PREFIX_ORG + String.format("%1$03d", order);
		return code;
	}

	public void saveUpdateChildCode(Organization organization) {
		List<Organization> organizations = organization.getChilds();
		
		if(organizations == null || organizations.size() < 1){
			return;
		}
		
		for (Iterator<Organization> iterator = organizations.iterator(); iterator.hasNext();) {
			Organization entity = iterator.next();
			
			entity.setCode(organization.getCode() +"_" + String.format("%1$03d", entity.getOrder()));
			
			this.save(entity);
		}
	}

	public List<Organization> findTopOrganizations() {
		
		return organizationDao.findTopOrganizations();
	}
	
	/**
	 * 根据店查驻店员 
	 * 
	 * @param shopId
	 * @return
	 */
	public List<Organization> findUserShopByShopId(Long shopId) {
		
		return organizationDao.findUserShopByShopId(shopId);
	}
	
	/**
	 * 根据店查区域经理
	 * 
	 * @param shopId
	 * @return
	 */
	public List<Organization> findUserDomainByShopId(Long shopId) {
		
		return organizationDao.findUserDomainByShopId(shopId);
	}
	/**
	 * 绩效确认，需要的人员名单
	 */
	public Page<Organization> findPageUser(Long userId, int pageNo, int pageSize) {
		Criteria criteria = organizationDao.createCriteria();
		criteria.addOrder(Order.asc(Organization.COLUMN_CODE));
		criteria.addOrder(Order.desc(Organization.COLUMN_ORDER));
		List<Organization> organizations =this.UserDomainLists(userId);
		if(null != organizations && organizations.size()>0){
			Long[] objId = new Long[organizations.size()];
			for(int i=0;i<organizations.size();i++){
				Organization organization =organizations.get(i);
				objId[i]=organization.getParent().getId();
			}
			criteria.createCriteria(Organization.COLUMN_PARENT).add(Restrictions.in("id",objId));
			criteria.add(Restrictions.eq(Organization.COLUMN_TYPE,OrganizationEnum.SHOP ));
			return this.findPage(criteria, pageNo, pageSize);
		}else{
			return null;
		}
		
	}
	/**
	 * 绩效确认，需要的人员名单
	 */
	public Page<Organization> findPageUser(Long[] objId, int pageNo, int pageSize) {
		if(objId.length >0){
			Criteria criteria = organizationDao.createCriteria();
			criteria.addOrder(Order.asc(Organization.COLUMN_CODE));
			criteria.addOrder(Order.desc(Organization.COLUMN_ORDER));
				criteria.createCriteria(Organization.COLUMN_PARENT).add(Restrictions.in("id",objId));
				criteria.add(Restrictions.eq(Organization.COLUMN_TYPE,OrganizationEnum.SHOP ));
				return this.findPage(criteria, pageNo, pageSize);
		}else{
			return null;
		}
		
	}
	/**
	 * 绩效确认，需要的人员名单--管理员获得所有的店
	 */
	public Page<Organization> findPageUser(int pageNo, int pageSize) {
			Criteria criteria = organizationDao.createCriteria();
			criteria.addOrder(Order.asc(Organization.COLUMN_CODE));
			criteria.addOrder(Order.desc(Organization.COLUMN_ORDER));
//				criteria.createCriteria(Organization.COLUMN_PARENT).add(Restrictions.in("id",objId));
				criteria.add(Restrictions.eq(Organization.COLUMN_TYPE,OrganizationEnum.SHOP ));
				return this.findPage(criteria, pageNo, pageSize);
	}
	/**
	 * 查询区域经理
	 * @return
	 */
	public List<Organization> UserDomainLists(Long userId){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq(Organization.COLUMN_OBJECT_ID, userId));
		criteria.add(Restrictions.eq(Organization.COLUMN_TYPE, OrganizationEnum.STAFF));
		return criteria.list();
	}
	/**
	 * 获得所有区域
	 * @return
	 */
	public Map<String, Organization> DomainMap(OrganizationEnum organizationEnum){
		Map<String, Organization> map = new HashMap<String, Organization>();
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("type",organizationEnum));
		List<Organization> organizations = criteria.list();
		for(int i=0;i<organizations.size();i++){
			Organization organization = organizations.get(i);
			boolean bo=true;
			for(int j=0;j<organizations.size();j++){
				Organization orga = organizations.get(j);
				if(orga.getParent() != null){
					if(organization.getId() == orga.getParent().getId()){
						bo = false;
					}
				}
			}
			if(bo){
				map.put(organization.getName(), organization);
			}
		}
		return map;
	}
	/**
	 * 获得所有区域
	 * @return
	 */
	public List<Organization> DomainList(){
		List<Organization> oList = new ArrayList<Organization>();
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("type", OrganizationEnum.ORG));
		List<Organization> organizations = criteria.list();
		for(int i=0;i<organizations.size();i++){
			Organization organization = organizations.get(i);
			boolean bo=true;
			for(int j=0;j<organizations.size();j++){
				Organization orga = organizations.get(j);
				if(orga.getParent() != null){
					if(organization.getId() == orga.getParent().getId()){
						bo = false;
					}
				}
			}
			if(bo){
				oList.add(organization);
			}
		}
		return oList;
	}
	/**
	 * 获得组织数据
	 * @return
	 */
	public Organization organizationKey(String name,OrganizationEnum organizationEnum){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("name", name));
		criteria.add(Restrictions.eq("type",organizationEnum));
		List<Organization> organizations = criteria.list();
		if(organizations.size()>0){
			return organizations.get(0);
		}
		return null;
	}
	/**
	 * 获得所有店铺的ID
	 * @param user
	 * @param pageNo
	 * @param pageSize
	 * @return
	 */
	public Set<Long> fianPage(User user){
//		Set<Long> id = new HashSet<Long>();
		Set<Long> shopId = new HashSet<Long>();
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("objectId", user.getId()));
		criteria.add(Restrictions.eq("type", OrganizationEnum.STAFF));
		List<Organization> organizations = criteria.list();
		if(organizations != null && organizations.size()>0){
		for(int i=0;i<organizations.size();i++){
			Organization organization = organizations.get(i);
		Criteria criteriA = organizationDao.createCriteria();
		if(!user.getPost().equals(PostType.Admin)){//修改查询方式   不用ID 查询 改用CODE查询
//			criteriA.createCriteria(Organization.COLUMN_PARENT).add(Restrictions.in("id",id));
			System.out.println(organization.getCode());
			criteriA.add(Restrictions.like(Organization.COLUMN_CODE, organization.getParent().getCode(),MatchMode.START));
		}
		criteriA.add(Restrictions.eq("type", OrganizationEnum.SHOP));
//		criteriA.createCriteria(Organization.COLUMN_PARENT).add(Restrictions.in("id",id));
		List<Organization> organizationA = criteriA.list();
		if(organizationA.size() >0){
			for(int j=0;j<organizationA.size();j++){
				shopId.add(organizationA.get(j).getObjectId());
			}
		}
			}
		}
		return shopId;
 	}
	/**
	 * 获得组织数据--店铺
	 * @return
	 */
	public Organization organizationShopKey(Long obeId,OrganizationEnum organizationEnum){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("objectId", obeId));
		criteria.add(Restrictions.eq("type",organizationEnum));
		List<Organization> organizations = criteria.list();
		if(organizations.size()>0){
			return organizations.get(0);
		}
		return null;
	}
	/**
	 * 获得组织数据--所有店铺
	 * @return
	 */
	public Map<String, Organization> organizationShopMap(){
		Map<String, Organization> map = new HashMap<String, Organization>();
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("type",OrganizationEnum.SHOP));
		List<Organization> organizations = criteria.list();
		for(int i=0;i<organizations.size();i++){
			Organization organization = organizations.get(i);
			if(!map.containsKey(organization.getName())){
				map.put(organization.getName(), organization);
			}
		}
		return map;
	}
	/**
	 * 根据objId 获得组织架构数据
	 * @param name
	 * @return
	 */
	public Organization organizationKey(Long id){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("objectId", id));
		List<Organization> organizations = criteria.list();
		if(organizations!=null&&organizations.size()>0){
			return organizations.get(0);
		}
		return null;
	}
	/**
	 * 当4S店需要改变区域的是否去判断  该店在组织架构上  下面是否还有驻店人员
	 * @param id
	 * @return
	 */
	public Boolean judgeOrganization(Long id){
		Criteria criteria = organizationDao.createCriteria();
		criteria.add(Restrictions.eq("objectId", id));
		criteria.add(Restrictions.eq("type", OrganizationEnum.SHOP));
		List<Organization> organizations = criteria.list();
		if(organizations.size()>0){
			for(Organization organization : organizations){
				if(organization.getChilds().size()>0){
					return true;
				}
			}
		}
		return false;
	}
	
	public List<Organization> findShopsByCurrentUser(){
		String userName = ThreadLocalHolder.get().toString();
		User user = userService.getUserByName(userName);
		
		return organizationDao.findShopsByCurrentUser(user);
	}
	
	public List<Organization> findShopsByCurrentUser(User user){
		
		return organizationDao.findShopsByCurrentUser(user);
	}
	
}
